/*
 * Copyright (c) 2017-2022, Lindenis Tech. Ltd.
 * All rights reserved.
 *
 * File:
 *
 * Description:
 *
 * Author:
 *      xiaoshujun@lindeni.com
 *
 * Create Date:
 *      2022/01/04
 *
 * History:
 *
 */

#include <stdio.h>
#include <string.h>
#include "iniparser/iniparser.h"
#include "osal_prop.h"

#define LINDSDK_INI_PATH        "/etc/lindsdk.ini"
#define LINDSDK_INI_PATH_DBG    CFG_PATH"/lindsdk.ini"
#define LINDSDK_INI_PATH_DBG2   "/tmp/lindsdk.ini"

static dictionary* g_ini = NULL;
static char g_ini_name[64] = {0};

int ldprop_init(const char * file_path)
{
    const char * ini_name = file_path;
    if (ini_name == NULL)
    {
        /*
         * try to find the default/debug system ini file
         */
        if (access(LINDSDK_INI_PATH_DBG, 0) == 0) {
            ini_name = LINDSDK_INI_PATH_DBG;
        } else if (access(LINDSDK_INI_PATH_DBG2, 0) == 0) {
            ini_name = LINDSDK_INI_PATH_DBG2;
        } else if (access(LINDSDK_INI_PATH, 0) == 0) {
            ini_name = LINDSDK_INI_PATH;
        } else {
            printf("do not find lindsdk conf file\n");
            return -1;
        }
    }

    /*
     * only support one instance
     */
    if (g_ini) {
        return 0;
    }

    g_ini = iniparser_load(ini_name);
    if (g_ini == NULL) {
        printf("load lindsdk conf file %s failed\n", ini_name);
        return -1 ;
    } else {
        printf("load lindsdk conf file %s ok!\n", ini_name);
    }
    strncpy(g_ini_name, ini_name, 63);

    return 0;
}

void ldprop_deinit()
{
    if (g_ini == NULL) {
        iniparser_freedict(g_ini);
        g_ini = NULL;
    }
}

const char * ldprop_get_string(const char * sec, const char * key, const char * def)
{
    char ini_node[128];
    if (g_ini == NULL || !iniparser_find_entry(g_ini, sec)) {
        return def;
    }

    sprintf(ini_node, "%s:%s", sec, key);
    return iniparser_getstring(g_ini, ini_node, def);
}

int ldprop_get_int(const char * sec, const char * key, int notfound)
{
    char ini_node[128];
    if (g_ini == NULL || !iniparser_find_entry(g_ini, sec)) {
        return notfound;
    }

    sprintf(ini_node, "%s:%s", sec, key);
    return iniparser_getint(g_ini, ini_node, notfound);
}

long int ldprop_get_longint(const char * sec, const char * key, long int notfound)
{
    char ini_node[128];
    if (g_ini == NULL || !iniparser_find_entry(g_ini, sec)) {
        return notfound;
    }

    sprintf(ini_node, "%s:%s", sec, key);
    return iniparser_getlongint(g_ini, ini_node, notfound);
}

int ldprop_get_boolean(const char * sec, const char * key, int notfound)
{
    char ini_node[128];
    if (g_ini == NULL || !iniparser_find_entry(g_ini, sec)) {
        return notfound;
    }

    sprintf(ini_node, "%s:%s", sec, key);
    return iniparser_getboolean(g_ini, ini_node, notfound);
}

double ldprop_get_double(const char * sec, const char * key, double notfound)
{
    char ini_node[128];
    if (g_ini == NULL || !iniparser_find_entry(g_ini, sec)) {
        return notfound;
    }

    sprintf(ini_node, "%s:%s", sec, key);
    return iniparser_getdouble(g_ini, ini_node, notfound);
}

const char * ldprop_get(const char * key)
{
    if (g_ini == NULL) {
        return NULL;
    }
    return iniparser_getstring(g_ini, key, NULL);
}

int ldprop_set(const char * key, const char * val)
{
    if (g_ini == NULL || key == NULL) {
        return -1;
    }

    int i = 0, len = strlen(key);
    for (i = 0; i < len; i++) {
        if (key[i] == ':') {
            break;
        }
    }

    /*
     * found ':'
     */
    if (i < len)
    {
        char * entry = malloc(i + 1);
        if (!entry) {
            return -1;
        }

        strncpy(entry, key, i);
        entry[i] = 0;

        if (!iniparser_find_entry(g_ini, entry)) {
            /*
             * not found entry, create it
             */
            if (iniparser_set(g_ini, entry, NULL)) {
                free(entry);
                return -1;
            }
        }

        free(entry);
    }

    return iniparser_set(g_ini, key, val);
}

int ldprop_sync()
{
    return ldprop_save(g_ini_name);
}

int ldprop_save(const char * file_path)
{
    if (g_ini == NULL) {
        return -1;
    }

    FILE * ini_fp = fopen(file_path, "w");
    if (!ini_fp) {
        printf("ini file: %s open failed\n", file_path);
        return -1;
    }

    iniparser_dump_ini(g_ini, ini_fp);
    fclose(ini_fp);

    return 0;
}

void ldprop_dump()
{
    if (g_ini != NULL) {
        iniparser_dump(g_ini, stdout);
    }
}

